package com.lizk.leetcode.integertoroman;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 12. 整数转罗马数字
 * https://leetcode-cn.com/problems/integer-to-roman/
 */
public class Client {

    private static final Logger logger = LoggerFactory.getLogger(Client.class);
    public static void main(String[] args) {
        Client client = new Client();
        JSON.toJSONString(client);
        logger.debug("{}:{}:{}",3,client.intToRoman(3),"III");
        logger.debug("{}:{}:{}",9,client.intToRoman(9),"IX");
        logger.debug("{}:{}:{}",1994,client.intToRoman(1994),"MCMXCIV");
        logger.debug("{}:{}:{}",10,client.intToRoman(10),"X");
        logger.debug("{}:{}:{}",5,client.intToRoman(5),"V");
        logger.debug("{}:{}:{}",50,client.intToRoman(50),"L");
        logger.debug("{}:{}:{}",3999,client.intToRoman(3999),"MMMCMXCIX");
        logger.debug("{}:{}:{}",388,client.intToRoman(388),"CCCLXXXVIII");
    }

    /**
     * 字符          数值
     * I             1
     * V             5
     * X             10
     * L             50
     * C             100
     * D             500
     * M             1000
     * 按照十进制来划分数据,然后9，5,4等特殊情况在一次10禁止的循环内处理
     *
     * @param num
     * @return
     */
    public String intToRoman(int num) {
        char [] result = new char[32];
        int [] step = new int[]{5000,1000,500,100,50,10,5,1};
        char [] value = new char[]{'*','M','D','C','L','X','V','I'};

        int sumCount = 0;
        int actualCount = 0;
        int resultIndex  = 0;
        for (int i = 1; i < step.length; i = i + 2) {
            //看数字中一共包含的本次进制数值的个数,例如数字 33中包含3个10
            sumCount = num / step[i];
            //如果个数为0，那么说明数字还不到这个进制的级别
            if (sumCount == 0 ){
                continue;
                //如果个数为9，需要特殊处理,需要展示的是当前进制的值对应的字母和当前进制往前两个位置的值对应的字母
            }else if (sumCount == 9 ){
                result[resultIndex++] = value[i];
                result[resultIndex++] = value[i-2];
                //如果个数为4，需要特殊处理,需要展示的是当前进制的值对应的字母和当前进制往前一个位置的值对应的字母
            }else if (sumCount == 4){
                result[resultIndex++] = value[i];
                result[resultIndex++] = value[i-1];
            }else{
                //一般情况下,也分两种情况一种是个数大于5，一种是个数小于5
                //个数小于5时不需要要展示当前进制值前一个数值对应的字母,例如, 当前进制为10，算出的进制值的个数为3，那么说明数值不到50，就不需要展示50对应的字母
                //反之，如果个数大于5的时候,说明需要展示当前进制值前一个数值对应的字母.
                actualCount = 0;
                if (num >= step[i-1]){
                    result[resultIndex++] = value[i-1];
                    //如果个数大于5的,时候,因为展示了一个50对应的字母,所以10这个值对应的字母只需要展示sumCount - 5个,所以这里把起始位置加了5
                    actualCount = 5;
                }

                while ( actualCount++ < sumCount) {
                    result[resultIndex++] = value[i];
                }
            }
            num = num - step[i] * sumCount;
        }
        return new String (result,0,resultIndex);
    }
}
